#ifndef VENUS_SHAPES_TRIANGLEMESH_H
#define VENUS_SHAPES_TRIANGLEMESH_H

#include "shape.h"

#include <assert.h>

#include <vector>

#include "geometry/point.h"
#include "geometry/normal.h"
#include "geometry/aabb.h"

namespace venus {
class Vector3;
typedef std::vector< SharedPtr<Shape> > ShapeSet;

class TriangleMesh : public Shape {
 public:
  TriangleMesh(Point *points, Normal *normals, float *tex_coords, int *vertex_indices,
               int vertex_count, int triangle_count)
      : points_(points), normals_(normals), tex_coords_(tex_coords),
        vertex_indices_(vertex_indices), vertex_count_(vertex_count),
        triangle_count_(triangle_count), bound_need_update_(true) {
  }
  ~TriangleMesh();
  void Scale2Size(float size);
  void Scale(float scale);
  void Translate(const Vector3 &offset);
  void Translate2Pos(const Point &pos);
  void GetTriangles(ShapeSet *triangles) const;
  AABB Bound() const;

  const Point *points() const { return points_; }
  const Normal *normals() const { return normals_; }
  const float *tex_coords() const { return tex_coords_; }
  const int *vertex_indices() const { return vertex_indices_; }
  int triangle_count() const { return triangle_count_; }
  int vertex_count() const { return vertex_count_; }
  const Point &point(int i) const { return points_[i]; }
  void set_point(int i, const Point &p) { points_[i] = p; }
  const Normal &normal(int i) const { return normals_[i]; }
  const float *tex_coord(int i) const { return &tex_coords_[i]; }
  int vertex_index(int i) const { return vertex_indices_[i]; }
  bool has_tex() const { return NULL != tex_coords_; }
private:
  void ComputeBound() const;
private:
  Point *points_;
  Normal *normals_;
  float *tex_coords_;
  int *vertex_indices_;
  int triangle_count_, vertex_count_;
  mutable AABB bound_;
  mutable bool bound_need_update_;
  //class Triangle should access the private data by accessors only
  friend class Triangle;
  DISABLE_COPY_AND_ASSIGN(TriangleMesh);
};
} // namespace venus

#endif // VENUS_SHAPES_TRIANGLEMESH_H
